<?php
namespace WDB\Analyzer;
use WDB,
    WDB\Exception;

/**
 *
 * @author Richard Ejem <richard(at)ejem.cz>

 * @property-read string $name
 * @property-read iTable[] $tables
 */
class Schema extends WDB\BaseObject implements iSchema
{
    /**@var WDB\Database*/
    protected $database;
    /**@var string*/
    protected $name;
    /**@var TableView[]*/
    protected $tables;
    /**@var array NeonWheel configuration*/
    protected $model;

    private $dbName;

    /**
     *
     * @param string schema name
     * @param WDB\Database connection
     * @throws Exception\SchemaNotFound
     */
    public function __construct($name, WDB\Database $database)
    {
        if (!$database->getDriver()->schemaExists($name))
        {
            throw new Exception\SchemaNotFound("Schema `$name` not found");
        }
        $this->name = $name;
        $this->database = $database;
        $this->dbName = $database->getName();
        $this->model = $this->initModel();
        $this->tables = $database->getDriver()->getTablesViews($this);
        foreach ($this->tables as $table)
        {
            $table->onSchemaConstructed();
        }
    }

    private function initModel()
    {
        $modelName = $this->database->getConnectionConfig()->model;
        if ($modelName === FALSE) return; //not using NW model configuration
        $modelDir = WDB\Config::read('modeldir');
        if ($modelName === NULL)
        {
            $lookPaths = array($modelDir.DIRECTORY_SEPARATOR.$this->name.'.nw');
        }
        else
        {
            $lookPaths = array(
                            $modelName,
                            $modelName.'.nw',
                            $modelDir.DIRECTORY_SEPARATOR.$modelName,
                            $modelDir.DIRECTORY_SEPARATOR.$modelName.'.nw',
                         );
        }

        $model = NULL;
        foreach ($lookPaths as $lookPath)
        {
            if (file_exists($lookPath))
            {
                $model = \NeonWheel::decode(file_get_contents($lookPath));
                break;
            }
        }
        if ($model === NULL)
        {
            if ($modelName !== NULL)
            {
                throw new WDB\Exception\ConfigInsufficient ("Model $modelName for schema ".$this->schema->getName()." was specified but not found");
            }
        }
        return $model;
    }

    // <editor-fold defaultstate="collapsed" desc="iSchema impl.">
    /**
     * schema name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * array of all tables in schema
     *
     * @return iTable[]
     */
    public function getTables()
    {
        return $this->tables;
    }

    public function getModel()
    {
        return $this->model;
    }

    public function getDatabase()
    {
        return $this->database;
    }

    // </editor-fold>

    public function __sleep ()
    {
        return array('name', 'tables', 'dbName');
    }

    public function __wakeup()
    {
        $this->database = WDB\Database::getInstance($this->dbName);
    }

}